﻿package core.ui.util
{
    import core.enum.*;
    import core.ui.controls.*;
    import flash.display.*;
    import flash.events.*;
    import flash.geom.*;

    public class DistortTool extends Sprite
    {
        var ed:Tuyitu;
        var editmask:Boolean;
        var raster:Sprite;
        var target:Bitmap;
        var preview:Sprite;
        var topleft:Sprite;
        var topright:Sprite;
        var bottomleft:Sprite;
        var bottomright:Sprite;
        var matrix:Matrix;
        var points:Array;
        var triangles:Array;
        var ch:Sprite;
        var md:Point;
        var mc:Point;
        var tl:Point;
        var tr:Point;
        var bl:Point;
        var br:Point;

        public function DistortTool(param1:Tuyitu)
        {
            this.md = new Point();
            this.mc = new Point();
            this.ed = param1;
            param1.addChild(this);
            param1.SetModal(this, false);
            param1.canvas.history.Prepare(Action.Distort);
            this.editmask = param1.canvas.layer.editMask;
            param1.canvas.layer.editMask = false;
            this.target = param1.canvas.layer.SetBitmapCutEditMode(param1.canvas.selection, Boolean(param1.canvas.document.anr == 0 && !param1.canvas.document.transparent), true);
            this.target.visible = false;
            this.preview = new Sprite();
            this.preview.x = this.target.x;
            this.preview.y = this.target.y;
            param1.canvas.layer.holder.addChild(this.preview);
            param1.canvas.RemoveSelection();
            this.raster = new Sprite();
            this.raster.doubleClickEnabled = true;
            this.raster.addEventListener(MouseEvent.MOUSE_DOWN, this.RasterMouseDown, false, 1, true);
            this.raster.addEventListener(MouseEvent.MOUSE_OVER, this.HandlerMouseOver, false, 1, true);
            this.raster.addEventListener(MouseEvent.DOUBLE_CLICK, this.OK, false, 1, true);
            addChild(this.raster);
            this.topleft = new Sprite();
            this.AddCorner(this.topleft);
            this.topright = new Sprite();
            this.AddCorner(this.topright);
            this.bottomleft = new Sprite();
            this.AddCorner(this.bottomleft);
            this.bottomright = new Sprite();
            this.AddCorner(this.bottomright);
            this.matrix = param1.canvas.document.transform.concatenatedMatrix.clone();
            this.matrix.tx = this.matrix.tx + param1.canvas.layer.offset.x * param1.canvas.document.scaleX;
            this.matrix.ty = this.matrix.ty + param1.canvas.layer.offset.y * param1.canvas.document.scaleY;
            var _loc_2:* = this.target.getBounds(this.target);
            var _loc_3:* = this.matrix.transformPoint(_loc_2.topLeft);
            var _loc_4:* = this.matrix.transformPoint(_loc_2.bottomRight);
            this.matrix.invert();
            this.topleft.x = _loc_3.x;
            this.topleft.y = _loc_3.y;
            this.topright.x = _loc_4.x;
            this.topright.y = _loc_3.y;
            this.bottomleft.x = _loc_3.x;
            this.bottomleft.y = _loc_4.y;
            this.bottomright.x = _loc_4.x;
            this.bottomright.y = _loc_4.y;
            stage.addEventListener(KeyboardEvent.KEY_UP, this.KeyUP, false, 0, true);
            param1.modal.addEventListener(MouseEvent.MOUSE_OVER, this.ResetMouse, false, 0, true);
            param1.modal.addEventListener(MouseEvent.MOUSE_DOWN, this.ClickOutside, false, 0, true);
            this.Init();
            return;
        }// end function

        private function AddCorner(KEY_UP:Sprite) : void
        {
            KEY_UP.addEventListener(MouseEvent.MOUSE_DOWN, this.HandlerMouseDown, false, 1, true);
            KEY_UP.addEventListener(MouseEvent.MOUSE_OVER, this.HandlerMouseOver, false, 1, true);
            KEY_UP.graphics.beginFill(15658734, 0);
            KEY_UP.graphics.drawRect(-7, -7, 15, 15);
            KEY_UP.graphics.beginFill(15658734);
            KEY_UP.graphics.drawRect(-4, -4, 9, 9);
            KEY_UP.graphics.beginFill(4040436);
            KEY_UP.graphics.drawRect(-3, -3, 7, 7);
            KEY_UP.graphics.endFill();
            addChild(KEY_UP);
            return;
        }// end function

        private function ResetMouse(event:Event) : void
        {
            this.ed.cursor.Set(ToolType.None);
            return;
        }// end function

        private function KeyUP(event:KeyboardEvent) : void
        {
            if (event.keyCode == 13)
            {
                this.OK();
            }
            else if (event.keyCode == 27)
            {
                this.Cancel();
            }
            return;
        }// end function

        public function ClickOutside(event:MouseEvent) : void
        {
            new ConfirmDialog(this.ed, U.RM("rm_apply_changes"), this.OK, this.Cancel);
            return;
        }// end function

        public function OK(event:Event = null) : void
        {
            this.ed.canvas.history.Commit();
            var _loc_2:* = new Bitmap(new BitmapData(this.ed.canvas.dw, this.ed.canvas.dh, true, 16777215));
            _loc_2.bitmapData.draw(this.ed.canvas.layer.holder);
            this.ed.canvas.layer.holder.removeChild(this.target);
            this.ed.canvas.layer.holder.removeChild(this.preview);
            if (this.ed.canvas.layer.bitmap.bitmapData != null)
            {
                this.ed.canvas.layer.bitmap.bitmapData.dispose();
                this.ed.canvas.layer.bitmap.bitmapData = null;
            }
            this.ed.canvas.layer.holder.addChild(_loc_2);
            this.ed.canvas.layer.RemoveBitmapEditMode();
            this.ed.canvas.UpdateAfterEdit();
            this.Close();
            return;
        }// end function

        public function Cancel(event:Event = null) : void
        {
            this.ed.canvas.SetSelection(this.ed.canvas.history.prepare.args[1]);
            this.target.visible = true;
            this.ed.canvas.layer.holder.removeChild(this.preview);
            this.ed.canvas.layer.RemoveBitmapEditMode();
            this.ed.canvas.UpdateAfterEdit();
            this.Close();
            return;
        }// end function

        public function Close() : void
        {
            this.ed.navigator.SetSelectionSize(0, 0);
            this.ed.modal.removeEventListener(MouseEvent.MOUSE_DOWN, this.ClickOutside, false);
            this.ed.modal.removeEventListener(MouseEvent.MOUSE_OVER, this.ResetMouse, false);
            stage.removeEventListener(KeyboardEvent.KEY_UP, this.KeyUP, false);
            this.ed.canvas.layer.editMask = this.editmask;
            this.ed.removeChild(this);
            this.ed.RemoveModal();
            return;
        }// end function

        private function HandlerMouseOver(event:MouseEvent) : void
        {
            switch(event.target as Sprite)
            {
                case this.topleft:
                case this.bottomright:
                case this.topright:
                case this.bottomleft:
                {
                    this.ed.cursor.Set(ToolType.MovePoint);
                    break;
                }
                case this.raster:
                {
                    this.ed.cursor.Set(ToolType.MoveDrag);
                    break;
                }
                default:
                {
                    break;
                }
            }
            return;
        }// end function

        private function HandlerMouseDown(event:MouseEvent) : void
        {
            this.ed.cursor.freeze = true;
            this.ch = event.target as Sprite;
            this.ch.startDrag();
            stage.addEventListener(MouseEvent.MOUSE_MOVE, this.Redraw, false, 1, true);
            stage.addEventListener(MouseEvent.MOUSE_UP, this.HandlerMouseUp, false, 1, true);
            return;
        }// end function

        private function HandlerMouseUp(event:MouseEvent) : void
        {
            this.ed.cursor.freeze = false;
            if (event.target != this.ch)
            {
                this.ed.cursor.Set(ToolType.None);
            }
            this.ch.stopDrag();
            stage.removeEventListener(MouseEvent.MOUSE_MOVE, this.Redraw, false);
            stage.removeEventListener(MouseEvent.MOUSE_UP, this.HandlerMouseUp, false);
            return;
        }// end function

        private function RasterMouseDown(event:MouseEvent) : void
        {
            this.ed.cursor.freeze = true;
            this.md.x = this.mouseX;
            this.md.y = this.mouseY;
            stage.addEventListener(MouseEvent.MOUSE_MOVE, this.RasterMouseMove, false, 0, true);
            stage.addEventListener(MouseEvent.MOUSE_UP, this.RasterMouseUp, false, 0, true);
            return;
        }// end function

        private function RasterMouseMove(event:MouseEvent) : void
        {
            this.mc.x = this.mouseX;
            this.mc.y = this.mouseY;
            this.topleft.x = this.topleft.x + (this.mc.x - this.md.x);
            this.topleft.y = this.topleft.y + (this.mc.y - this.md.y);
            this.topright.x = this.topright.x + (this.mc.x - this.md.x);
            this.topright.y = this.topright.y + (this.mc.y - this.md.y);
            this.bottomleft.x = this.bottomleft.x + (this.mc.x - this.md.x);
            this.bottomleft.y = this.bottomleft.y + (this.mc.y - this.md.y);
            this.bottomright.x = this.bottomright.x + (this.mc.x - this.md.x);
            this.bottomright.y = this.bottomright.y + (this.mc.y - this.md.y);
            this.md.x = this.mc.x;
            this.md.y = this.mc.y;
            this.Redraw();
            return;
        }// end function

        private function RasterMouseUp(event:MouseEvent) : void
        {
            this.ed.cursor.freeze = false;
            if (event.target != this.raster)
            {
                this.ed.cursor.Set(ToolType.None);
            }
            stage.removeEventListener(MouseEvent.MOUSE_MOVE, this.RasterMouseMove, false);
            stage.removeEventListener(MouseEvent.MOUSE_UP, this.RasterMouseUp, false);
            return;
        }// end function

        private function Init() : void
        {
            var _loc_1:Number = NaN;
            var _loc_2:Number = NaN;
            var _loc_3:Number = NaN;
            var _loc_4:Number = NaN;
            var _loc_5:* = 6;
            this.points = new Array();
            this.triangles = new Array();
            var _loc_6:* = this.target.width / 2;
            var _loc_7:* = this.target.height / 2;
            var _loc_8:* = this.target.width / (_loc_5 + 1);
            var _loc_9:* = this.target.height / (_loc_5 + 1);
            _loc_1 = 0;
            while (_loc_1 < _loc_5 + 2)
            {
                
                _loc_2 = 0;
                while (_loc_2 < _loc_5 + 2)
                {
                    
                    _loc_3 = _loc_1 * _loc_8;
                    _loc_4 = _loc_2 * _loc_9;
                    this.points.push({x:_loc_3, y:_loc_4, sx:_loc_3, sy:_loc_4});
                    _loc_2 = _loc_2 + 1;
                }
                _loc_1 = _loc_1 + 1;
            }
            _loc_1 = 0;
            while (_loc_1 <= _loc_5)
            {
                
                _loc_2 = 0;
                while (_loc_2 <= _loc_5)
                {
                    
                    this.triangles.push([this.points[_loc_2 + _loc_1 * (_loc_5 + 2)], this.points[_loc_2 + _loc_1 * (_loc_5 + 2) + 1], this.points[_loc_2 + (_loc_1 + 1) * (_loc_5 + 2)]]);
                    this.triangles.push([this.points[_loc_2 + (_loc_1 + 1) * (_loc_5 + 2) + 1], this.points[_loc_2 + (_loc_1 + 1) * (_loc_5 + 2)], this.points[_loc_2 + _loc_1 * (_loc_5 + 2) + 1]]);
                    _loc_2 = _loc_2 + 1;
                }
                _loc_1 = _loc_1 + 1;
            }
            this.Redraw();
            return;
        }// end function

        public function Redraw(... args) : void
        {
            args = NaN;
            var _loc_3:Object = null;
            var _loc_4:Object = null;
            var _loc_5:Object = null;
            var _loc_6:Number = NaN;
            var _loc_7:Number = NaN;
            var _loc_8:Number = NaN;
            var _loc_9:Number = NaN;
            var _loc_10:Number = NaN;
            var _loc_11:Number = NaN;
            var _loc_12:Number = NaN;
            var _loc_13:Number = NaN;
            var _loc_14:Number = NaN;
            var _loc_15:Number = NaN;
            var _loc_16:Number = NaN;
            var _loc_17:Number = NaN;
            var _loc_18:Object = null;
            var _loc_19:Number = NaN;
            var _loc_20:Number = NaN;
            var _loc_21:Number = NaN;
            var _loc_22:Number = NaN;
            this.preview.graphics.clear();
            this.raster.graphics.clear();
            this.raster.graphics.beginFill(0, 0);
            this.raster.graphics.lineStyle(0, 15658734);
            this.raster.graphics.moveTo(this.topleft.x, this.topleft.y);
            this.raster.graphics.lineTo(this.topright.x, this.topright.y);
            this.raster.graphics.lineTo(this.bottomright.x, this.bottomright.y);
            this.raster.graphics.lineTo(this.bottomleft.x, this.bottomleft.y);
            this.raster.graphics.lineTo(this.topleft.x, this.topleft.y);
            this.raster.graphics.endFill();
            this.tl = this.matrix.transformPoint(new Point(this.topleft.x, this.topleft.y));
            this.tr = this.matrix.transformPoint(new Point(this.topright.x, this.topright.y));
            this.br = this.matrix.transformPoint(new Point(this.bottomright.x, this.bottomright.y));
            this.bl = this.matrix.transformPoint(new Point(this.bottomleft.x, this.bottomleft.y));
            var _loc_23:* = this.bl.x - this.tl.x;
            var _loc_24:* = this.bl.y - this.tl.y;
            var _loc_25:* = this.br.x - this.tr.x;
            var _loc_26:* = this.br.y - this.tr.y;
            args = this.points.length;
            while (--args >= 0)
            {
                
                _loc_18 = this.points[args];
                _loc_19 = _loc_18.x / this.target.width;
                _loc_20 = _loc_18.y / this.target.height;
                _loc_21 = this.tl.x + _loc_20 * _loc_23;
                _loc_22 = this.tl.y + _loc_20 * _loc_24;
                _loc_18.sx = _loc_21 + _loc_19 * (this.tr.x + _loc_20 * _loc_25 - _loc_21);
                _loc_18.sy = _loc_22 + _loc_19 * (this.tr.y + _loc_20 * _loc_26 - _loc_22);
            }
            var _loc_27:* = new Matrix();
            var _loc_28:* = new Matrix();
            --args = this.triangles.length;
            while (--_loc_2 >= 0)
            {
                
                _loc_3 = this.triangles[--args][0];
                _loc_4 = this.triangles[_loc_2][1];
                _loc_5 = this.triangles[_loc_2][2];
                _loc_6 = _loc_3.sx;
                _loc_7 = _loc_3.sy;
                _loc_8 = _loc_4.sx;
                _loc_9 = _loc_4.sy;
                _loc_10 = _loc_5.sx;
                _loc_11 = _loc_5.sy;
                _loc_12 = _loc_3.x;
                _loc_13 = _loc_3.y;
                _loc_14 = _loc_4.x;
                _loc_15 = _loc_4.y;
                _loc_16 = _loc_5.x;
                _loc_17 = _loc_5.y;
                _loc_28.tx = _loc_12;
                _loc_28.ty = _loc_13;
                _loc_28.a = (_loc_14 - _loc_12) / this.target.width;
                _loc_28.b = (_loc_15 - _loc_13) / this.target.width;
                _loc_28.c = (_loc_16 - _loc_12) / this.target.height;
                _loc_28.d = (_loc_17 - _loc_13) / this.target.height;
                _loc_27.a = (_loc_8 - _loc_6) / this.target.width;
                _loc_27.b = (_loc_9 - _loc_7) / this.target.width;
                _loc_27.c = (_loc_10 - _loc_6) / this.target.height;
                _loc_27.d = (_loc_11 - _loc_7) / this.target.height;
                _loc_27.tx = _loc_6;
                _loc_27.ty = _loc_7;
                _loc_28.invert();
                _loc_28.concat(_loc_27);
                this.preview.graphics.beginBitmapFill(this.target.bitmapData, _loc_28, false, true);
                this.preview.graphics.moveTo(_loc_6, _loc_7);
                this.preview.graphics.lineTo(_loc_8, _loc_9);
                this.preview.graphics.lineTo(_loc_10, _loc_11);
                this.preview.graphics.endFill();
            }
            return;
        }// end function

    }
}
